//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using OpenLS.Core.Serialization;

namespace OpenLS.Spreadsheet
{
    public class Top10FormattingRule : StandardConditionalFormattingRule
    {
        internal override ConditionalFormattingType Type
        {
            get { return ConditionalFormattingType.Top10; }
        }
        internal override bool Apply(Cell cell)
        {
            return ApplyStyle(cell, AppliesTo(cell));
        }
        protected override void ReadInner2(ReadContext context)
        {
            Percent = context.GetOptionalBoolean("percent", false);
            Bottom = context.GetOptionalBoolean("bottom", false);
            Rank = context.GetOptionalUIntegerAsInteger("rank", 10);
                
        }
        internal override void WriteInner2(WriteContext context)
        {
            context.SetOptionalBoolean("percent", Percent, false);
            context.SetOptionalBoolean("bottom", Bottom, false);
            context.SetOptionalUIntegerAsInteger("rank", Rank, 10);

        }

        private int _rank = 10;

        public int Rank
        {
            get { return _rank; }
            set { if (value < 0)
                throw new ArgumentException("value");
                _rank = value; NotifyPropertyChanged("Rank");}
        }

        private bool _percent;

        public bool Percent
        {
            get { return _percent; }
            set { _percent = value; NotifyPropertyChanged("Percent");}
        }
        private bool bottom;

        public bool Bottom
        {
            get { return bottom; }
            set { bottom = value; NotifyPropertyChanged("Bottom");}
        }


        bool AppliesTo (Cell cell)
        {
            Debug.WriteLine("Applied to " + cell.Label);
            if (!(cell.Value is double))
            {
                return false;
            }
            var n = (double)cell.Value;
            double threshold = _distribution.GetTopValue(Rank, Bottom, this.Percent);
            bool result;
            if (Bottom)
                result = n <= threshold;
            else
                result = n >= threshold;
            Debug.WriteLine(result);
            return result;
        }


        internal override void ApplyRange(Range range)
        {
            _distribution = new CellValueDistribution(range);
        }

        private CellValueDistribution _distribution;
    }
}
